package com.yungee.util;

import com.google.common.base.Strings;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;

import java.math.BigDecimal;
import java.util.Calendar;
import java.util.Date;
import java.util.Objects;

/**
 * @author samuel
 * @date 2018/12/4
 */
@Slf4j
public class DateUtil {

	public static final DateTimeFormatter YMD_DATE_TIME_FORMATTER = DateTimeFormat.forPattern("yyyyMMdd");
	public static final DateTimeFormatter Y_M_D_H_M_S_DATE_TIME_FORMATTER = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss");
	public static final DateTimeFormatter Y_M_D_H_M_DATE_TIME_FORMATTER = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm");
	public static final DateTimeFormatter Y_M_DATE_TIME_FORMATTER = DateTimeFormat.forPattern("yyyy-MM");
	public static final DateTimeFormatter Y_M_D_DATE_TIME_FORMATTER = DateTimeFormat.forPattern("yyyy-MM-dd");
	public static final int ONE_DAY_MILLISECOND = 24 * 60 * 60 * 1000;

	public static final String YMD_DATE_TIME_FORMAT = "yyyyMMdd";
	public static final String Y_M_D_H_M_S_DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
	public static final String Y_M_D_H_M_DATE_TIME_FORMAT ="yyyy-MM-dd HH:mm";
	public static final String Y_M_DATE_TIME_FORMAT = "yyyy-MM";
	public static final String Y_M_D_DATE_TIME_FORMAT = "yyyy-MM-dd";

	/**
	 * 格式化日期
	 *
	 * @param pattern 指定类型的日期样式
	 * @param date    要格式化的日期
	 * @return 格式化后的指定样式的字符串日期
	 */
	public static String format(String pattern, Date date) {
		DateTimeFormatter dateTimeFormatter = DateTimeFormat.forPattern(pattern);
		return date == null || Strings.isNullOrEmpty(pattern) ? null : (new DateTime(date)).toString(dateTimeFormatter);
	}

	public static String getSimpleYmdByDate(Date date) {
		return date == null ? null : (new DateTime(date)).toString(YMD_DATE_TIME_FORMATTER);
	}

	public static String getSimpleYMDHmsByDate(Date date) {
		return date == null ? null : (new DateTime(date)).toString(Y_M_D_H_M_S_DATE_TIME_FORMATTER);
	}

	public static String getSimpleYMDHmByDate(Date date) {
		return date == null ? null : (new DateTime(date)).toString(Y_M_D_H_M_DATE_TIME_FORMATTER);
	}

	public static String getYmByDate(Date date) {
		return date == null ? null : (new DateTime(date)).toString(Y_M_DATE_TIME_FORMATTER);
	}
	public static String getYmdByDate(Date date) {
		return date == null ? null : (new DateTime(date)).toString(Y_M_D_DATE_TIME_FORMATTER);
	}


	public static Date parseDate(String pattern, String dateStr) {
		if (StringUtils.isBlank(dateStr) || StringUtils.isBlank(pattern)) {
			return null;
		}

		DateTimeFormatter dateTimeFormatter = DateTimeFormat.forPattern(pattern);
		DateTime dateTime = dateTimeFormatter.parseDateTime(dateStr);
		return dateTime.toDate();
	}

	public static Date parseDate(String str) {
		if (StringUtils.isEmpty(str)) {
			return null;
		}

		DateTime dateTime = Y_M_D_H_M_S_DATE_TIME_FORMATTER.parseDateTime(str);
		return dateTime.toDate();
	}

	public static Date parseSimpleYmd(String dateStr) {
		if (StringUtils.isEmpty(dateStr)) {
			return null;
		}

		return YMD_DATE_TIME_FORMATTER.parseDateTime(dateStr).toDate();
	}

	public static Date parseSimpleYmdHms(String dateStr) {
		if (StringUtils.isEmpty(dateStr)) {
			return null;
		}

		return Y_M_D_H_M_S_DATE_TIME_FORMATTER.parseDateTime(dateStr).toDate();
	}

	/**
	 * 当天时间0点的毫秒数
	 */
	public static long getTodayStartTime() {
		return getDateStartTime(new Date());
	}

	/**
	 * 当天时间0点的毫秒数
	 */
	public static long getDateStartTime(Date date) {
		if (Objects.isNull(date)){
			return 0;
		}

		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.set(Calendar.HOUR_OF_DAY, 0);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		calendar.set(Calendar.MILLISECOND, 0);
		return calendar.getTimeInMillis();
	}

	public static long getCurrentTime() {
		Calendar calendar = Calendar.getInstance();
		long result = calendar.getTimeInMillis();
		return result;
	}

	public static Date getMonthLastTime(Date date) {
		Calendar cal = Calendar.getInstance();
		if (date != null) {
			cal.setTime(date);
		}
		cal.set(cal.get(Calendar.YEAR), cal.get(Calendar.MONDAY), cal.get(Calendar.DAY_OF_MONTH), 0, 0, 0);
		cal.set(Calendar.DAY_OF_MONTH, cal.getActualMaximum(Calendar.DAY_OF_MONTH));
		cal.set(Calendar.HOUR_OF_DAY, cal.getActualMaximum(Calendar.HOUR_OF_DAY));
		cal.set(Calendar.SECOND, cal.getActualMaximum(Calendar.SECOND));
		cal.set(Calendar.MINUTE, cal.getActualMaximum(Calendar.MINUTE));
		cal.set(Calendar.MILLISECOND, cal.getActualMaximum(Calendar.MILLISECOND));
		return cal.getTime();
	}

	/**
	 * 获取 当前月的 开始时间
	 * @param date
	 * @return
	 */
	public static Date getMonthFirstTime(Date date) {
		Calendar cal = Calendar.getInstance();
		if (date != null) {
			cal.setTime(date);
		}
		cal.set(cal.get(Calendar.YEAR), cal.get(Calendar.MONDAY), 1, 0, 0, 0);
		cal.set(Calendar.MILLISECOND, 0);
		return cal.getTime();
	}

	public static int durationDays(Date date) {
		return durationDays(date, new Date());
	}


	/**
	 * 比较两个日期相隔天数
	 * @param begin
	 * @param end
	 * @return
	 */
	public static int durationDays(Date begin, Date end) {
		long beginTime = getDateStartTime(begin);
		long endTime = getDateStartTime(end);
		long durationTime = beginTime > endTime ? beginTime - endTime : endTime - beginTime;

		return (int) (durationTime / ONE_DAY_MILLISECOND);
	}

	/**
	 * 当前到 月底 秒数
	 * @return
	 */
	public static int getCurrent2MonthLastSecond() {
		Date current = new Date();

		Calendar cal = Calendar.getInstance();
		cal.set(cal.MONTH, cal.get(Calendar.MONTH) + 1);
		cal.set(Calendar.DAY_OF_MONTH, 1);
		cal.set(Calendar.HOUR_OF_DAY, 0);
		cal.set(Calendar.MINUTE, 0);
		cal.set(Calendar.SECOND, 0);
		cal.set(Calendar.MILLISECOND, 0);

		return (int) (cal.getTimeInMillis() - current.getTime()) / 1000;
	}

	/**
	 * 当前到 月底 秒数
	 * @return
	 */
	public static int getCurrent2NDaysSecond(int n) {
		Date current = new Date();

		Calendar cal = Calendar.getInstance();
		cal.add(Calendar.DAY_OF_MONTH, n + 1);
		cal.set(Calendar.HOUR_OF_DAY, 0);
		cal.set(Calendar.MINUTE, 0);
		cal.set(Calendar.SECOND, 0);
		cal.set(Calendar.MILLISECOND, 0);

		return (int) (cal.getTimeInMillis() - current.getTime()) / 1000;
	}

	/**
	 * 指定 日期 前 n 天 的开始时间
	 * @param date
	 * @param beforeDays
	 * @return
	 */
	public static Date getBeforeNDaysDate(Date date, int beforeDays) {
		if (Objects.isNull(date)) {
			date = new Date();
		}

		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		cal.add(Calendar.DAY_OF_MONTH, - beforeDays);
		cal.set(Calendar.HOUR_OF_DAY, 0);
		cal.set(Calendar.MINUTE, 0);
		cal.set(Calendar.SECOND, 0);
		cal.set(Calendar.MILLISECOND, 0);

		return cal.getTime();
	}
	public static Date getAfterNDaysDate(Date date, int afterDays) {
		if (Objects.isNull(date)) {
			date = new Date();
		}

		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		cal.add(Calendar.DAY_OF_MONTH, afterDays);
		cal.set(Calendar.HOUR_OF_DAY, 0);
		cal.set(Calendar.MINUTE, 0);
		cal.set(Calendar.SECOND, 0);
		cal.set(Calendar.MILLISECOND, 0);

		return cal.getTime();
	}
	public static int getWeekDay(Date date){
		Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
		int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);
		return dayOfWeek;
	}
}
